﻿using System.Collections;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Text;

public class HttpUtil
{
    public CookieContainer cookies = new CookieContainer();
    /// <summary>
    /// Executes an HTTP GET request against the Url specified, returning the 
    /// entire response body in string form.
    /// </summary>
    /// <param name="url">The URL to request</param>
    /// <param name="requireHttp200">
    /// Boolean indicating whether or not to return 
    /// null if the repsonse status code is not 200 (OK).
    /// </param>
    /// <returns>
    /// The response body or null if the response status is required to 
    /// be 200 (OK) but is not
    /// </returns> 
    public string PerformHttpGet(string url, CookieContainer cookie, bool requireHttp200, params KeyValuePair<string, string>[] headers)
    {
        string responseBody = null;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Timeout = 10000;
        request.CookieContainer = cookie;
        foreach (var KV in headers)
        {
            if (KV.Key.ToUpper() == "UserAgent".ToUpper())
            {
                request.UserAgent = KV.Value;
                continue;
            }
            if (KV.Key.ToUpper() == "Referer".ToUpper())
            {
                request.Referer = KV.Value;
                continue;
            }
            request.Headers.Add(KV.Key, KV.Value);
        }
        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            if (!requireHttp200 || response.StatusCode == HttpStatusCode.OK)
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    if (responseStream != null)
                    {
                        using (StreamReader responseReader = new StreamReader(responseStream))
                        {
                            responseBody = responseReader.ReadToEnd();
                        }
                    }
                }
            }
            cookies = cookie;
            response.Close();//获取Cookie
        }
        return responseBody;
    }



    /// <summary>
    /// Executes an HTTP POST against the Url specified with the supplied post data, 
    /// returning the entire response body in string form.
    /// </summary>
    /// <param name="url">The URL to post to</param>
    /// <param name="postData">The x-www-form-urlencoded data to post to the URL</param>
    /// <param name="requireHttp200">
    /// Boolean indicating whether or not to return 
    /// null if the repsonse status code is not 200 (OK).
    /// </param>
    /// <returns>
    /// The response body or null if the response status is required to 
    /// be 200 (OK) but is not
    /// </returns>
    public string PerformHttpPost(string url, string postData, CookieContainer cookie, Encoding encod, bool AjaxReq = false, string contentType = "application/json", params KeyValuePair<string, string>[] headers)
    {
        return PerformHttpPost(url, postData, cookie, encod, out WebHeaderCollection head, AjaxReq, contentType, headers);
    }
    /// <summary>
    /// 执行HTTP POST请求。
    /// </summary>
    /// <param name="url">目标URL</param>
    /// <param name="postData">POST数据，格式为JSON字符串，例如："{\"username\":\"john_doe\",\"password\":\"123456\"}"</param>
    /// <param name="cookieContainer">Cookie容器</param>
    /// <param name="encoding">编码方式</param>
    /// <param name="responseHeader">响应头</param>
    /// <param name="ajaxReq">是否是Ajax请求</param>
    /// <param name="contentType">Content-Type，默认为application/json</param>
    /// <param name="headers">自定义头部信息</param>
    /// <returns>响应体或null（如果响应状态码不是200且requireHttp200为true）</returns>
    public string PerformHttpPost(string url, string postData, CookieContainer cookieContainer, Encoding encoding, out WebHeaderCollection responseHeader, bool ajaxReq = false, string contentType = "application/json", params KeyValuePair<string, string>[] headers)
    {
        string responseBody = null;

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.Method = "POST";
        request.ContentType = contentType;
        request.ContentLength = Encoding.UTF8.GetByteCount(postData);
        request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36";
        request.CookieContainer = cookieContainer;
        request.Timeout = 90000;
        if (ajaxReq)
        {
            request.Headers.Add("ajaxRequest", "true");
            request.Headers.Add("X-Requested-With", "XMLHttpRequest");
        }
        foreach (var KV in headers)
        {
            if (KV.Key.ToUpper() == "UserAgent".ToUpper())
            {
                request.UserAgent = KV.Value;
                continue;
            }
            if (KV.Key.ToUpper() == "Referer".ToUpper())
            {
                request.Referer = KV.Value;
                continue;
            }

            request.Headers.Add(KV.Key, KV.Value);
        }

        using (StreamWriter requestWriter = new StreamWriter(request.GetRequestStream()))
        {
            requestWriter.Write(postData);
        }

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        {
            responseHeader = response.Headers;
            using (Stream responseStream = response.GetResponseStream())
            {
                if (responseStream != null)
                {
                    using (StreamReader responseReader = new StreamReader(responseStream, encoding))
                    {
                        responseBody = responseReader.ReadToEnd();
                    }
                }
            }
            response.Close();
            cookies = cookieContainer;
        }

        return responseBody;
    }
    public static String getCookieValue(String cookie, String name)
    {
        Regex regex = new Regex("(" + name + ")=([^;]*)(;|$)");
        Match value = regex.Match(cookie);
        if (value.Length > 0)
        {
            return value.Groups[2].ToString();
        }
        return "";
    }
    public static List<Cookie> GetAllCookies(CookieContainer cc)
    {
        if (cc == null)
            return null;
        List<Cookie> lstCookies = new List<Cookie>();
        Hashtable table = (Hashtable)cc.GetType().InvokeMember("m_domainTable",
            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField |
            System.Reflection.BindingFlags.Instance, null, cc, new object[] { });
        foreach (object pathList in table.Values)
        {
            SortedList lstCookieCol = (SortedList)pathList.GetType().InvokeMember("m_list",
                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField
                | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { });
            foreach (CookieCollection colCookies in lstCookieCol.Values)
                foreach (Cookie c in colCookies) lstCookies.Add(c);
        }
        return lstCookies;
    }
}
